/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.comments.application.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.cxf.common.util.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.Assert;

import com.foreveross.bsl.comments.application.CommentModuleException;
import com.foreveross.bsl.comments.application.CommentService;
import com.foreveross.bsl.comments.application.vo.CommentFeedbackVo;
import com.foreveross.bsl.comments.application.vo.CommentVo;
import com.foreveross.bsl.comments.model.domain.Comment;
import com.foreveross.bsl.comments.model.domain.CommentFeedback;
import com.foreveross.bsl.comments.model.domain.repository.CommentFeedbackRepository;
import com.foreveross.bsl.comments.model.domain.repository.CommentRepository;
import com.foreveross.bsl.common.utils.context.ContextThead;
import com.foreveross.bsl.common.utils.mapper.BeanMapper;
import com.foreveross.bsl.common.utils.web.QueryFilter;
import com.foreveross.bsl.common.utils.web.QueryOrder;
import com.foreveross.bsl.common.utils.web.QuerySpecs;
import com.foreveross.bsl.system.application.ApplicationRegisterApplication;
import com.foreveross.bsl.system.application.vo.ApplicationRegisterVO;

/**
 * xxx
 *
 * @author Wangyi
 * @version v1.0
 *
 * @date 2013-7-17
 *
 */
@Named("commentService")
public class CommentServiceImpl implements CommentService{
	
//	@Inject
//	private CommentRepository cmtRepo;
	
//	@Inject
//	private CommentFeedbackRepository cmtFeedbackRepo;

	@Inject 
	private ApplicationRegisterApplication applicationRegisterApplication;
	
	private final CommentRepository getCommentRepository(){
		return new Comment().getEntityRepository(CommentRepository.class);
	}
	
	private final CommentFeedbackRepository getCommentFeedbackRepository(){
		return new CommentFeedback().getEntityRepository(CommentFeedbackRepository.class);
	}
	
	
	/**
	 * 根据appId切换db线程
	 * @param appId
	 */
	private void changeDBThread(String appId){
		String appKey = applicationRegisterApplication.getAppKeyByAppId(appId);		
		ApplicationRegisterVO applicationRegisterVO = applicationRegisterApplication.getByAppKey(appKey);
		ContextThead.setThreadVar(applicationRegisterVO.getUsername());
	}
	
	@Override
	public void addComment(String comment, String type, String loginName, String appKey) {
		Assert.notNull(comment);
		Assert.notNull(loginName);
		Assert.notNull(appKey);
		
		String appId = applicationRegisterApplication.getAppIdByAppKey(appKey);
		changeDBThread(appId);
		
		Comment cmt =new Comment();
		cmt.setAppId(appId);
		cmt.setContent(comment);
		cmt.setCreateTime(new Date());
		cmt.setLoginName(loginName);
		cmt.setStatus(Comment.CommentStatusEnum.PENDING);
		cmt.setType(type);
		//TODO 需要调用安全中心接口查询到用户名吗？
//		cmt.setUserName(userName);
		cmt.save();
	}
	
	@Override
	public void addComment(CommentVo comment) {
		Comment cmt=BeanMapper.map(comment, Comment.class);
		
		changeDBThread(comment.getAppId());
		
		cmt.setCreateTime(new Date());
		if(cmt.getStatus() == null){
			cmt.setStatus(Comment.CommentStatusEnum.PENDING);
		}
		cmt.save();
	}

	@Override
	public void feedbackComment(String commentId, String content, String loginName) {
		Comment cmt=getCommentRepository().findOne(commentId);
		if(cmt==null){
			throw new CommentModuleException("不存在意见对象："+commentId);
		}
		CommentFeedback cmtFeedback=new CommentFeedback();
		cmtFeedback.setCommentId(commentId);
		cmtFeedback.setContent(content);
		cmtFeedback.setCreateTime(new Date());
		cmtFeedback.setFeedbackor(loginName);
		cmtFeedback.save();
	}

	@Override
	public void deleteComment(String commentId) {
		this.getCommentFeedbackRepository().deleteByCommentId(commentId);
		this.getCommentRepository().delete(commentId);
	}

	@Override
	public CommentVo getById(String commentId) {
		Comment cmt=this.getCommentRepository().findOne(commentId);
		return BeanMapper.map(cmt, CommentVo.class);
	}
	
	@Override
	public Page<CommentVo> findComments(int pageNumber, int pageSize, QuerySpecs querySpecs) {
		if (querySpecs == null) {
			querySpecs = new QuerySpecs();
		}
		QueryOrder qo=querySpecs.getOrder("createTime");
		if (qo == null ) {
			querySpecs.setOrder("createTime", QueryOrder.Direction.DESC);
		}
		Pageable pageable=new PageRequest(pageNumber-1, pageSize);
		Page<Comment> page=this.getCommentRepository().findByQuerySpecs(querySpecs, pageable);
		List<CommentVo> list=BeanMapper.mapList(page.getContent(), CommentVo.class);
		Page<CommentVo> voPage=new PageImpl<CommentVo>(list, pageable, page.getTotalElements());
		return voPage;
	}
	

	@Override
	public Page<CommentFeedbackVo> findCommentFeedbacks(String commentId, int pageNumber, int pageSize, QuerySpecs querySpecs) {
		if (querySpecs == null) {
			querySpecs = new QuerySpecs();
		}
		QueryOrder qo=querySpecs.getOrder("createTime");
		if (qo == null ) {
			querySpecs.setOrder("createTime", QueryOrder.Direction.DESC);
		}
		querySpecs.addFilter(QueryFilter.eq("commentId", commentId));
		Pageable pageable=new PageRequest(pageNumber-1, pageSize);
		Page<CommentFeedback> page=this.getCommentFeedbackRepository().findByQuerySpecs(querySpecs, pageable);
		List<CommentFeedbackVo> list=BeanMapper.mapList(page.getContent(), CommentFeedbackVo.class);
		Page<CommentFeedbackVo> voPage=new PageImpl<CommentFeedbackVo>(list, pageable, page.getTotalElements());
		return voPage;
	}
	
	@Override
	public List<CommentVo> findAllCommentByCommentStatus(String status,String hirerName) {
		//切换数据库路由
		ContextThead.setThreadVar(hirerName);
		Query query = Query.query(Criteria.where("status").is(status));
		query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
		List<Comment> comments = getCommentRepository().findListByQuery(query);
		List<CommentVo> commentVos = BeanMapper.mapList(comments, CommentVo.class);
		return commentVos;
	}

	@Override
	public void updateComments(List<CommentVo> commentVos,String hierName) {
		List<Comment> comments = new ArrayList<Comment>();
		ContextThead.setThreadVar(hierName);
		for(int i = 0; i < commentVos.size(); i++){
			Comment comment = getCommentRepository().findOne(commentVos.get(i).getId());
			Comment.CommentStatusEnum enum1 = Comment.CommentStatusEnum.valueOf(commentVos.get(i).getStatus().name());
			comment.setStatus(enum1);
			comments.add(comment);
		}
		getCommentRepository().delete(comments);
		getCommentRepository().save(comments);
	}
	
	@Override
	public CommentVo updateEntity(CommentVo entity) {
		Comment comment = new Comment();
		BeanMapper.copy(entity, comment);
		comment.save();
		BeanMapper.copy(comment,entity);
		return entity;
	}
	
	@Override
	public Page<CommentVo> findComments(String appKey,int pageNumber, int pageSize) {
		if(!StringUtils.isEmpty(appKey)){
			String appId = applicationRegisterApplication.getAppIdByAppKey(appKey);
			changeDBThread(appId);
		}else{
			return null;
		}
		Query query=new Query();
		query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
		Pageable pageable=new PageRequest(pageNumber-1, pageSize);
		Page<Comment> page=this.getCommentRepository().findByQuery(query, pageable);
		List<CommentVo> list=BeanMapper.mapList(page.getContent(), CommentVo.class);
		for(int i = 0; i < list.size(); i++){
			List<CommentFeedbackVo> feedbacks = findCommentFeedbacks(list.get(i).getId());
			list.get(i).setFeedbacks(feedbacks);
		}
		Page<CommentVo> voPage=new PageImpl<CommentVo>(list, pageable, page.getTotalElements());
		return voPage;
	}
	
	@Override
	public List<CommentFeedbackVo> findCommentFeedbacks(String commentId) {
		Query query=Query.query(Criteria.where("commentId").is(commentId));
		query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
		List<CommentFeedback> feedbacks=this.getCommentFeedbackRepository().findListByQuery(query);
		List<CommentFeedbackVo> list=BeanMapper.mapList(feedbacks, CommentFeedbackVo.class);
		return list;
	}

	@Override
	public void addFeedback(CommentFeedbackVo commentFeedbackVo) {
		Assert.notNull(commentFeedbackVo);
		
		CommentFeedback feedback = BeanMapper.map(commentFeedbackVo, CommentFeedback.class);
		feedback.save();
	}
	
	@Override
	public void addFeedback(String commentId,String content,String feedbackor) {
		Assert.notNull(commentId);
		Assert.notNull(content);
		Assert.notNull(feedbackor);
		
		CommentFeedbackVo feedbackVo = new CommentFeedbackVo();
		feedbackVo.setCommentId(commentId);
		feedbackVo.setFeedbackor(feedbackor);
		feedbackVo.setContent(content);
		feedbackVo.setCreateTime(new Date());
		
		CommentFeedback feedback = BeanMapper.map(feedbackVo, CommentFeedback.class);
		feedback.save();
	}

	@Override
	public List<CommentVo> findAllCommentByCommentStatusAndAppKey(
			String status, String hirerName, String appKey) {
		String appId = applicationRegisterApplication.getAppIdByAppKey(appKey);
		//切换数据库路由
		ContextThead.setThreadVar(hirerName);
		Query query = Query.query(Criteria.where("status").is(status).and("appId").is(appId));
		query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
		List<Comment> comments = getCommentRepository().findListByQuery(query);
		List<CommentVo> commentVos = BeanMapper.mapList(comments, CommentVo.class);
		return commentVos;
	}
	
}
